package com.tdh.controller;

import com.alibaba.fastjson.JSON;
import com.tdh.exception.MyException;
import com.tdh.pojo.*;
import com.tdh.service.*;
import com.tdh.utils.FilesUtil;
import com.tdh.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Controller
@RequestMapping("ck")
@Slf4j
public class CkController {

    @Resource
    private CkCkdxService ckdxService;

    @Resource
    private CkCkxzService ckxzService;

    @Resource
    private TsDmService tsDmService;

    @Resource
    private TsBzdmService tsBzdmService;

    @Resource
    private CkXzdwService ckXzdwService;

    @Resource
    private CkJzService jzService;

    @RequestMapping("query")
    public String showQuery() {
        return "view/query";
    }

    @RequestMapping("showApplication")
    public String showApplication() {
        return "view/application";
    }

    @RequestMapping("frameTable")
    public ModelAndView showFrameTable() {
        ModelAndView mav = new ModelAndView("view/frameTable");
        mav.addObject("identityList", tsBzdmService.queryIdentity());
        mav.addObject("areaList", tsBzdmService.queryArea());
        mav.addObject("certificateList", tsDmService.queryZjlx());
        return mav;
    }

    /**
     * 实现分页查询查控对象列表
     *
     * @param zt    状态
     * @param ah    案号
     * @param mc    名称
     * @param zjhm  证件号码
     * @param start 开始行
     * @param limit 每页条数
     * @return xml字符串
     */
    @RequestMapping(value = "/queryCkdx", produces = {"application/xml;charset=UTF-8"})
    @ResponseBody
    public String queryCkdx(@RequestParam("zt") String[] zt, @RequestParam("ah") String ah,
                            @RequestParam("mc") String mc, @RequestParam("zjhm") String zjhm,
                            @RequestParam("start") int start, @RequestParam("limit") int limit) {

        log.debug("状态：{}，案号：{}，名称：{}，证件号码：{}", Arrays.toString(zt), ah, mc, zjhm);

        List<CkCkdx> ckdxList = ckdxService.queryCkdx(zt, ah, mc, zjhm, start - 1, limit);
        int totalNumber = ckdxService.countCkdx(zt, ah, mc, zjhm);

        return ckdxService.getXml(ckdxList, totalNumber);
    }

    /**
     * 查询状态列表，代码和名称
     *
     * @return TsDm列表
     */
    @RequestMapping(value = "/queryZt", produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public Results<List<TsDm>> queryZt() {

        List<TsDm> tsDmList = tsDmService.queryZt();
        return Results.success("查询状态列表成功", tsDmList);
    }

    /**
     * 批量删除
     *
     * @param ids 查控对象id 流水号
     * @param <T> 结果类
     * @return 结果类
     */
    @RequestMapping(value = "/deleteCkdxes")
    @ResponseBody
    public <T> Results<T> deleteCkdxes(@RequestBody String[] ids) {

        log.debug("删除查控对象流水号: {}", Arrays.toString(ids));
        int deleteCkdx = ckdxService.deleteCkdxes(ids);
        int deleteCkxz = ckxzService.deleteCkxzes(ids);
        if (deleteCkdx > 0 && deleteCkxz > 0) {
            log.info("删除用户，id为：{}", Arrays.toString(ids));
            return Results.success("删除成功");
        } else {
            return Results.error("删除失败");
        }
    }

    @RequestMapping("/saveCkdxes")
    @ResponseBody
    public <T> Results<T> saveCkdxes(@RequestParam("type") String type, @RequestBody List<SaveDTO> saveDTOList, HttpServletRequest request) throws IOException {

        log.debug("查控对象：{}", saveDTOList);

        return ckdxService.saveCkdxes(saveDTOList);

    }

    /**
     * 显示表单页面
     *
     * @param type 页面类型 新增、编辑
     * @param id 登记批次
     * @return ModelAndView
     */
    @RequestMapping("/showApplicationPage")
    public ModelAndView showApplicationPage(@RequestParam("type") String type, @RequestParam("id") String id) {

        ModelAndView mav = new ModelAndView("view/application");
        mav.addObject("type", type);

        mav.addObject("companyMap", ckXzdwService.queryXzdw());

        List<CkCkxz> ckxzList = new ArrayList<>();
        List<String> xzdwList = new ArrayList<>();
        List<CkJz> jzList = new ArrayList<>();

        //查看或编辑页面
        if (id != null && !"".equals(id)) {

            //获取查控对象列表
            ckxzList = ckxzService.queryBatch(id);

            //获取需要勾选的协执对象复选框
            xzdwList = ckxzService.queryCheckedXzdw(id);

            jzList = jzService.queryJz(ckxzList.get(0).getDjpc());


        }
        mav.addObject("ckxzes", JSON.toJSONString(ckxzList));
        mav.addObject("xzdw", JSON.toJSONString(xzdwList));
        mav.addObject("jzs", JSON.toJSONString(jzList));

        return mav;
    }

    /**
     * 保存上传的图片
     *
     * @param file 接收文件
     * @param request HttpServletRequest
     * @return 保存路径
     * @throws Exception 异常
     */
    @RequestMapping(value = "/uploadFile", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    @ResponseBody
    public Results<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {

        String uploadName;
        String dateStr = StringUtil.getNowDate("yyyyMMdd");

        Results<Map<String, String>> results;

        if (!file.isEmpty()) { //有文件传入

            //设置路径
            String path = FilesUtil.getTempFilePath("/temp/"+dateStr+"/");
            String originalFileName = file.getOriginalFilename();
            assert originalFileName != null;
            String fileType = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);

            //保存到临时文件夹
            uploadName = FilesUtil.uploadImg(file, path);


            Map<String, String> map = new HashMap<>();
            map.put("saveName", uploadName);
            map.put("realPath", path);
            map.put("fileType", fileType);
            map.put("datePath", dateStr);

            //存入原始文件名
            map.put("originName", originalFileName);

            results = Results.success("上传成功", map);
        } else {
            results = Results.error("上传失败，文件不存在");
        }
        return results;
    }

    /**
     * 文件下载
     *
     * @param response 响应
     * @param filePath 文件路径
     * @param fileName 文件名称
     */
    @RequestMapping("/downloadFile")
    public void downloadFile(HttpServletResponse response, @RequestParam(value="filePath") String filePath, @RequestParam(value="fileName") String fileName) {

        String path = filePath + "\\" + fileName;
        FileInputStream fis;
        try {

            //读取要下载的文件，保存到文件输入流
            fis = new FileInputStream(path);

            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GBK"), StandardCharsets.ISO_8859_1));    //设置文件下载头
            response.setContentType("multipart/form-data");                                  //自动判断下载文件类型

            //创建缓冲区
            byte[] b = new byte[1024];

            //循环将输入流中的内容读取到缓冲区中
            int len;
            while ((len = fis.read(b)) > 0) {
                response.getOutputStream().write(b, 0, len);
            }
            response.flushBuffer();
            fis.close();
        } catch (IOException e){
            throw new MyException("下载失败", e);
        }
    }

    /**
     * 删除新上传未保存的文件
     * @param deletePathArr 文件路径列表
     * @param <T> Result
     * @return Result
     */
    @RequestMapping("/deleteTempFile")
    @ResponseBody
    public <T> Results<T> deleteTempFile(@RequestBody List<String> deletePathArr) {

        //删除成功或删除文件中不包含新增文件
        if (deletePathArr.size() <= 0 || FilesUtil.deleteFile(deletePathArr)) {
            return Results.success("删除上传文件成功");
        } else {
            return Results.error("删除上传文件失败");
        }
    }
}